<?php

declare(strict_types=1);

namespace App\Controller\Admin;

use App\Model\Admin\Admin;
use App\Model\ChargeOption;
use App\Model\Device;
use App\Model\Finance;
use App\Model\Station;
use Hyperf\DbConnection\Db;
use Hyperf\Redis\Redis;
use Hyperf\HttpServer\Contract\RequestInterface;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Psr\Http\Message\ResponseInterface;
use RedisException;
use Trait\ResponseMsg;
use App\Model\Normal;
use Hyperf\Di\Annotation\Inject;
use App\Controller\AbstractController;
use App\Model\Distributors;
use Util\Common;

class FinanceController extends AbstractController
{
    use ResponseMsg;

    protected Redis $redis;
    protected Normal $normal;

    #[Inject]
    protected ChargeOption $chargeOption;

    #[Inject]
    protected Distributors $distributors;

    #[Inject]
    protected Device $device;

    #[Inject]
    protected Admin $admin;

    public function __construct()
    {
        $this->redis = container()->get(Redis::class);
        $this->normal = container()->get(Normal::class);
    }

    /**
     * 列表
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface|RedisException
     */
    public function getList(RequestInterface $request): ResponseInterface
    {
        try {
            $info = $this->admin->getInfo($request);
            if (!$info) {
                return $this->error(code: '400', msg: '登录态失效 请重新登录');
            }

            // 获取基本参数
            $page = $request->inputs(['page', 'limit', 'distributor_id', 'keyword', 'admin']);
            // 单独处理时间参数
            $time = $request->input('time', []);

            $model = Finance::query()
                ->when($page['distributor_id'] ?? null, function ($query, $distributorId) {
                    return $query->where('distributor_id', $distributorId);
                })
                ->when(!empty($time) && is_array($time), function ($query) use ($time) {
                    return $query->whereBetween('created_at', [
                        ($time[0] ?? '') . ' 00:00:00',
                        ($time[1] ?? '') . ' 23:59:59'
                    ]);
                })
                ->when($page['keyword'] ?? null, function ($query, $keyword) {
                    return $query->where(function($q) use ($keyword) {
                        $q->where('card', 'like', '%' . $keyword . '%')
                            ->orWhere('card_user', 'like', '%' . $keyword . '%');
                    });
                })
                ->when($page['admin'] ?? null, function ($query, $admin) {
                    return $query->whereHas('admin', function($q) use ($admin) {
                        $q->where('name', 'like', '%'.$admin.'%');
                    });
                });

            $data['total'] = $model->count();
            $data['list'] = $model
                ->orderByDesc('id')
                ->offset(($page['page'] - 1) * $page['limit'])
                ->limit($page['limit'])
                ->with(['admin', 'distributor'])
                ->get();

            return $this->success($data);
        } catch (\Exception $e) {
            return $this->error(1001, $e->getMessage() . $e->getTraceAsString());
        }
    }


    public function export(RequestInterface $request)
    {
        $page = $request->inputs(['page', 'limit', 'distributor_id', 'keyword', 'admin']);
        // 单独处理时间参数
        $time = $request->input('time', []);
        $model = Finance::query()
            ->when($page['distributor_id'] ?? null, function ($query, $distributorId) {
                return $query->where('distributor_id', $distributorId);
            })
            ->when(!empty($time) && is_array($time), function ($query) use ($time) {
                return $query->whereBetween('created_at', [
                    ($time[0] ?? '') . ' 00:00:00',
                    ($time[1] ?? '') . ' 23:59:59'
                ]);
            })
            ->when($page['keyword'] ?? null, function ($query, $keyword) {
                return $query->where(function($q) use ($keyword) {
                    $q->where('card', 'like', '%' . $keyword . '%')
                        ->orWhere('card_user', 'like', '%' . $keyword . '%');
                });
            })
            ->when($page['admin'] ?? null, function ($query, $admin) {
                return $query->whereHas('admin', function($q) use ($admin) {
                    $q->where('name', 'like', '%'.$admin.'%');
                });
            });
        $data['list'] = $model
            ->orderByDesc('id')
            ->offset(($page['page'] - 1) * $page['limit'])
            ->limit($page['limit'])
            ->with(['admin', 'distributor'])
            ->get();
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();
        // 设置 Excel 文档的头部
        $sheet->setCellValue('A1', '分销商名称');
        $sheet->setCellValue('B1', '审核员昵称');
        $sheet->setCellValue('C1', '提现金额');
        $sheet->setCellValue('D1', '银行卡号');
        $sheet->setCellValue('E1', '开户名');
        $sheet->setCellValue('F1', '银行名称');
        $sheet->setCellValue('G1', '备注');
        $sheet->setCellValue('H1', '操作时间');
        foreach (range('A', 'H') as $columnID) {
            $sheet->getColumnDimension($columnID)->setAutoSize(true);
        }
        $styleArray = [
            'alignment' => [
                'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
            ],
        ];
        $sheet->getStyle('A:H')->applyFromArray($styleArray);
        $row = 2;
        foreach ($data['list'] as $item) {
            $sheet->setCellValue('A' . $row, $item->distributor->name);
            $sheet->setCellValue('B' . $row, $item->admin->name);
            $sheet->setCellValue('C' . $row, $item->money);
            $sheet->setCellValue('D' . $row, $item->card);
            $sheet->setCellValue('E' . $row, $item->card_user);
            $sheet->setCellValue('F' . $row, $item->card_name);
            $sheet->setCellValue('G' . $row, $item->remark);
            $sheet->setCellValue('H' . $row, $item->created_at);
            $row++;
        }
        // 将 Spreadsheet 对象写入 XLSX 文件
        $writer = new Xlsx($spreadsheet);
        // 创建临时文件
        $publicPath = BASE_PATH . '/public/upload/xls/';
        $fileName = date('YmdHis', time()) . '-finance.xlsx';
        $temp_file = $publicPath . $fileName;
        // 保存到临时文件
        $writer->save($temp_file);
        return $this->success(['url' => Common::MAIN_HOST . '/upload/xls/' . $fileName]);

    }

    /**修改状态
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function changeStatus(RequestInterface $request): ResponseInterface
    {
        $status = $request->input('status', 0, 'int');
        $id = $request->input('id', 0, 'int');
        if (!$id) {
            return $this->error(code: 1001, msg: '缺失参数id');
        }
        $this->station->where('id', $id)->update(['is_active' => $status]);
        return $this->success(msg: '修改成功');
    }

    /**
     * 创建审核记录
     * @param RequestInterface $request
     * @return ResponseInterface
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function create(RequestInterface $request): ResponseInterface
    {
        try {
            $data = $request->post();
            if (empty($data['distributor_id'])) {
                return $this->error(code: 1001, msg: '请选择分销商');
            }
            $distributor_info = $this->distributors->find($data['distributor_id']);
            if (!$distributor_info) {
                return $this->error(code: 1001, msg: '分销商不存在');
            }
            if($data['money'] > $distributor_info['balance']){
                return $this->error(code: 1001, msg: '分销商余额不足');
            }
            $data['admin_id'] = $this->admin->getInfo($request)['id'];
            $data['new_balance'] = $data['balance'] - $data['money'];
            Db::transaction(function ()use($data,$distributor_info) {
                Finance::create($data);
                // 修改经销商余额
                $distributor_info->balance = $data['new_balance'];
                $distributor_info->save();
            });
            return $this->success();
        } catch (\Exception $e) {
            return $this->error(1001, $e->getMessage() . $e->getTraceAsString());
        }
    }
}
